import logging
import os
import sys
from datetime import date


class ColorFormatter(logging.Formatter):
    grey = '\x1b[38;21m'
    blue = '\x1b[38;5;39m'
    yellow = '\x1b[33;21m'
    red = '\x1b[31m'
    bold_red = '\x1b[1;31m'
    reset = '\x1b[0m'

    fmt = "%(asctime)s - %(name)s - %(levelname)8s - %(message)s (%(filename)s:%(lineno)d)"
    FORMATS = {
        logging.DEBUG: grey + fmt + reset,
        logging.INFO: blue + fmt + reset,
        logging.WARNING: yellow + fmt + reset,
        logging.ERROR: red + fmt + reset,
        logging.CRITICAL: bold_red + fmt + reset,
    }

    def format(self, record):
        log_fmt = self.FORMATS.get(record.levelno, self._fmt)
        formatter = logging.Formatter(log_fmt, datefmt="%Y-%m-%d %H:%M:%S")
        return formatter.format(record)


def setup_logging(log_level: str = "INFO") -> logging.Logger:
    os.makedirs("logs", exist_ok=True)

    log_level = log_level.upper()
    logger = logging.getLogger()
    logger.setLevel(log_level)

    # 清除默认 handler
    logger.handlers.clear()

    # 控制台日志（带颜色）
    console_handler = logging.StreamHandler(sys.stdout)
    console_handler.setLevel(log_level)
    console_handler.setFormatter(ColorFormatter())

    logger.addHandler(console_handler)

    # 文件日志
    log_filename = f"logs/app_{date.today():%Y_%m_%d}.log"
    file_handler = logging.FileHandler(log_filename, encoding="utf-8")
    file_handler.setLevel(logging.DEBUG)
    file_fmt = "%(asctime)s - %(name)s - %(levelname)8s - %(message)s (%(filename)s:%(lineno)d)"
    file_handler.setFormatter(logging.Formatter(file_fmt, datefmt="%Y-%m-%d %H:%M:%S"))

    logger.addHandler(file_handler)

    # 清除 Uvicorn 的默认 handler，避免控制台重复日志
    for name in ["uvicorn", "uvicorn.error", "uvicorn.access"]:
        # 获取到uvicorn的相关logger
        uvicorn_logger = logging.getLogger(name)
        # 清除默认 handler
        uvicorn_logger.handlers.clear()

        uvicorn_logger.setLevel(logging.INFO)
        # 输出到文件
        uvicorn_logger.addHandler(file_handler)
        # 输出到控制台
        uvicorn_logger.addHandler(console_handler)
        # 设置 propagate 为 False，避免重复输出
        uvicorn_logger.propagate = False
    return logger
